#include "doorbell_video.h"

#include "esp_camera.h"

#define TAG "video"

#define CAM_PIN_PWDN 40
#define CAM_PIN_RESET -1   // software reset will be performed
#define CAM_PIN_VSYNC 41
#define CAM_PIN_HREF 39
#define CAM_PIN_PCLK 34
#define CAM_PIN_XCLK 37
#define CAM_PIN_SIOD 0
#define CAM_PIN_SIOC 1
#define CAM_PIN_D0 9
#define CAM_PIN_D1 11
#define CAM_PIN_D2 12
#define CAM_PIN_D3 10
#define CAM_PIN_D4 33
#define CAM_PIN_D5 35
#define CAM_PIN_D6 36
#define CAM_PIN_D7 38

static camera_config_t camera_config = {
    .pin_pwdn      = CAM_PIN_PWDN,
    .pin_reset     = CAM_PIN_RESET,
    .pin_xclk      = CAM_PIN_XCLK,
    .pin_sccb_sda  = CAM_PIN_SIOD,
    .pin_sccb_scl  = CAM_PIN_SIOC,
    .sccb_i2c_port = 0,   // 使用i2c0

    .pin_d7    = CAM_PIN_D7,
    .pin_d6    = CAM_PIN_D6,
    .pin_d5    = CAM_PIN_D5,
    .pin_d4    = CAM_PIN_D4,
    .pin_d3    = CAM_PIN_D3,
    .pin_d2    = CAM_PIN_D2,
    .pin_d1    = CAM_PIN_D1,
    .pin_d0    = CAM_PIN_D0,
    .pin_vsync = CAM_PIN_VSYNC,
    .pin_href  = CAM_PIN_HREF,
    .pin_pclk  = CAM_PIN_PCLK,

    // XCLK 20MHz or 10MHz for OV2640 double FPS (Experimental)
    .xclk_freq_hz = 20000000,
    .ledc_timer   = LEDC_TIMER_0,
    .ledc_channel = LEDC_CHANNEL_0,
    // 像素格式
    .pixel_format = PIXFORMAT_JPEG,      // YUV422,GRAYSCALE,RGB565,JPEG
    .frame_size   = FRAMESIZE_240X240,   // QQVGA-UXGA, For ESP32, do not use sizes above QVGA when not JPEG. The performance of the ESP32-S series has improved a lot, but JPEG mode always gives better frame rates.

    .jpeg_quality = 12,                   // 0-63, for OV series camera sensors, lower number means higher quality
    .fb_count     = 1,                    // When jpeg mode is used, if fb_count more than one, the driver will work in continuous mode.
    .fb_location  = CAMERA_FB_IN_PSRAM,   // 缓冲区存储位置: 在外置的内存中
    .grab_mode    = CAMERA_GRAB_LATEST,   // 图像抓取模式:
};
void doorbell_video_Init(void)
{
    // initialize the camera
    esp_err_t err = esp_camera_init(&camera_config);
    if(err != ESP_OK)
    {
        ESP_LOGE(TAG, "Camera Init Failed");
        return;
    }
    ESP_LOGI(TAG, "Camera Init Failed");
}

camera_fb_t *pic;
//
void doorbell_video_GetPic(uint8_t **buff, size_t *buffLen)
{
    // 从摄像头获取一张图片
    pic = esp_camera_fb_get();
    if(pic)
    {
        *buffLen = pic->len;
        *buff    = pic->buf;
    }
}

// 释放图片
void doorbell_video_ReturnPic(void)
{
    if(pic)
    {
        esp_camera_fb_return(pic);
        pic = NULL;
    }
}
